package controller

import (
	. "api/model"
	. "api/util"
	. "api/service"
	"net/http"
	"strconv"
	"github.com/gin-gonic/gin"
)

type (
	NewUser struct {
		Phone        string `json:"phone"`
		Password     string `json:"password"`
		Vcode        string `json:"vcode"`
		Master       int    `json:"master"`
		SourceUserId int    `json:"source_user_id"`
	}
	UserRet struct {
		Cid          int    `json:"cid"`
		Phone        string `json:"phone"`
		Token        string `json:"token"`
	}
	UserRet2 struct {
		Cid          int    `json:"cid"`
		Phone        string `json:"phone"`
		Token        string `json:"token"`
		Pid		     string `json:"pid"`
	}
	Auth struct {
		Phone        string	`json:"phone"`
		Token        string `json:"token"`
	}
)

func Register(c *gin.Context) {
	nu := NewUser{}

	err := c.BindJSON(&nu)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
		return
	}

	_, err = strconv.Atoi(nu.Phone)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
		return
	}

	if len(nu.Phone) != 11 {
		c.JSON(http.StatusOK, gin.H{"error": "电话号码位数错误"})
		return
	}

	if len(nu.Password) < 6 || len(nu.Password) > 32 {
		c.JSON(http.StatusOK, gin.H{"error": "密码不足6位或多于32位"})
		return
	}

	if !(len(nu.Vcode) == 4 || len(nu.Vcode) == 6) {
		c.JSON(http.StatusOK, gin.H{"error": "验证码须4位或6位"})
		return
	}

	cm := Customer{}
	n, cid, pid, token, err := cm.Register(nu.Phone, nu.Password, nu.Master, nu.Vcode)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"status": 200, "msg": "success", "code": n,"data": UserRet2{cid, nu.Phone, token, pid}})
}

func Login(c *gin.Context) {
	nu := NewUser{}

	err := c.BindJSON(&nu)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
	}

	_, err = strconv.Atoi(nu.Phone)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
		return
	}

	if len(nu.Phone) != 11 {
		c.JSON(http.StatusOK, gin.H{"error": "电话号码位数错误"})
		return
	}

	if len(nu.Password) < 6 || len(nu.Password) > 32 {
		c.JSON(http.StatusOK, gin.H{"error": "密码不足6位或多于32位"})
		return
	}

	cm := Customer{}
	cid, token, err := cm.Login(nu.Phone, nu.Password)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"status": 200, "msg": "success", "data": UserRet{cid, nu.Phone, token}})
}

func AuthUser(c *gin.Context) {
	a := Auth{}
	err := c.BindJSON(&a)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
	}

	claims, err := ParseCliamsToken(a.Token)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
		return
	}

	id := int(claims.Id)
	phone := a.Phone

	cm := Customer{}
	err = cm.AuthUser(id, phone)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"status": 200, "msg": "success"})
}

func ForgotPassword(c *gin.Context) {
	nu := NewUser{}

	err := c.BindJSON(&nu)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
	}

	_, err = strconv.Atoi(nu.Phone)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
		return
	}

	if len(nu.Phone) != 11 {
		c.JSON(http.StatusOK, gin.H{"error": "手机格式错误"})
		return
	}

	if len(nu.Password) < 6 || len(nu.Password) > 32 {
		c.JSON(http.StatusOK, gin.H{"error": "密码不足6位或多于32位"})
		return
	}

	if !(len(nu.Vcode) == 4 || len(nu.Vcode) == 6) {
		c.JSON(http.StatusOK, gin.H{"error": "验证码须4位或6位"})
		return
	}

	cm := Customer{}
	err = cm.ForgotPassword(nu.Phone, nu.Password, nu.Vcode)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"status": 200, "msg": "success"})
}

func GetVcode(c *gin.Context) {
	phone := c.Query("phone")

	if len(phone) != 11 {
		c.JSON(http.StatusOK, gin.H{"error": "手机格式错误"})
		return
	}

    vcode := MakeVcode(4)

	v := Vcode{}

	err := v.SaveSession(phone, vcode)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
		return
	}

	err = SendMessage(phone, vcode, "1606145")
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"status": 200, "msg": "success", "data": vcode})
}